package site.zhouinfo.file;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

public class FTPUtil {

    public static final String STR_ENTER;
    //可以是FTP的IP地址，也可以是对应的域名
    private static String IP = "***FTP_IP***";
    private static String FTP_USER = "***FTP_USER_NAME***";
    private static String FTP_PWD = "***FTP_PASSWORD***";
    private static FTPClient instances = null;

    static {
        STR_ENTER = System.getProperty("line.separator");
    }

    /**
     * 初始化
     */
    public static void init() {
        FTPUtil.instances = FTPUtil.getInstances();
    }

    /**
     * 销毁
     */
    public static void distroy() {
        FTPUtil.close();
    }

    /**
     * 获取FTPClient单例实例
     */
    private synchronized static FTPClient getInstances() {
        if (FTPUtil.instances == null) {
            FTPUtil.instances = new FTPClient();
            try {
                FTPUtil.instances.connect(FTPUtil.IP);
                FTPUtil.instances.login(FTPUtil.FTP_USER, FTPUtil.FTP_PWD);
            } catch (IOException e) {
                FTPUtil.close();
                System.err.println("FTP登录异常");
            }
        }
        return FTPUtil.instances;
    }

    private synchronized static void close() {
        try {
            if (FTPUtil.instances != null) {
                FTPUtil.instances.logout();
                FTPUtil.instances.disconnect();
            }
            FTPUtil.instances = null;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 测试FTP连接是否正常
     */
    public static boolean testConnection() {
        boolean flag = true;
        FTPClient client = null;
        try {
            client = new FTPClient();
            client.connect(FTPUtil.IP);
            flag = client.login(FTPUtil.FTP_USER, FTPUtil.FTP_PWD);
        } catch (Exception e) {
            flag = false;
            client = null;
            System.out.println("FTP无法登陆");
        } finally {
            if (client != null) {
                try {
                    client.logout();
                    client.disconnect();
                } catch (IOException e1) {
                }
                client = null;
            }
        }
        return flag;
    }

    /**
     * 向FTP服务器上传文件
     *
     * @param path FTP服务器路径
     * @param name 文件名
     * @param file 上传的文件
     */
    public static void uploadFile(String path, String name, File file) {
        FileInputStream fis = null;
        FTPClient ftpClient = FTPUtil.getInstances();
        try {
            fis = new FileInputStream(file);
            FTPUtil.makdirs(path);
            ftpClient.changeWorkingDirectory(path); //设置上传目录
            ftpClient.setControlEncoding("UTF-8");
            ftpClient.setBufferSize(1024 * 10);
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); //设置文件类型（二进制）
            ftpClient.storeFile(name, fis);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("FTP客户端出错！", e);
        } finally {
            FTPUtil.safeClose(fis);
        }
    }

    /**
     * 上传一个输入流
     *
     * @param path FTP服务器路径
     * @param name 文件名
     * @param is   上传的文件
     */
    public static void uploadFormIs(String path, String name, InputStream is) {
        FTPClient ftpClient = FTPUtil.getInstances();
        try {
            FTPUtil.makdirs(path);
            ftpClient.changeWorkingDirectory(path); //设置上传目录
            ftpClient.setControlEncoding("UTF-8");
            ftpClient.setBufferSize(1024 * 10);
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); //设置文件类型（二进制）
            ftpClient.storeFile(name, is);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            FTPUtil.safeClose(is);
        }
    }

    /**
     * 向FTP服务器上传一个字符串
     */
    public static void uploadString(String path, String name, String str) {
        InputStream is = null;
        try {
            is = new ByteArrayInputStream(str.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        uploadFormIs(path, name, is);
    }

    /**
     * 从FTP服务器下载文件
     *
     * @param remoteFileName ftp上的文件路径目录
     * @param file           要保存到本地的文件file
     */
    public static void downloadFile(String remoteFileName, File file) {
        FTPClient ftpClient = FTPUtil.getInstances();
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            ftpClient.setBufferSize(1024 * 10);
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); //设置文件类型（二进制）
            ftpClient.retrieveFile(remoteFileName, fos);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("FTP客户端出错！", e);
        } finally {
            FTPUtil.safeClose(fos);
        }
    }

    /**
     * 从FTP中删除文件
     */
    public static boolean deleteFile(String filePath) {
        FTPClient ftpClient = FTPUtil.getInstances();
        boolean flag = false;
        try {
            flag = ftpClient.deleteFile(filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 创建多层文件夹
     */
    public static void makdirs(String path) {
        try {
            FTPClient ftpClient = getInstances();
            String[] paths = path.split("/");
            ftpClient.changeWorkingDirectory("/");
            for (String p : paths) {
                if (p.matches("[^/\\\\]+$")) {
                    ftpClient.makeDirectory(p);
                    ftpClient.changeWorkingDirectory(p);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("FTP客户端出错！", e);
        }
    }

    /**
     * 列出路径下的所有文件的文件名
     */
    public static List<String> listFile(String path) {
        FTPClient ftpClient = FTPUtil.getInstances();
        List<String> fileLists = new LinkedList<String>();
        FTPFile[] ftpFiles = null;// 获得指定目录下所有文件名
        try {
            ftpFiles = ftpClient.listFiles(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        for (int i = 0; ftpFiles != null && i < ftpFiles.length; i++) {
            FTPFile file = ftpFiles[i];
            if (file.isFile()) {
                fileLists.add(file.getName());
            }
        }
        return fileLists;
    }

    /**
     * 从FTP中获取文件输入流
     */
    public static InputStream getObjInputStream(String filePath) {
        FTPClient ftpClient = FTPUtil.getInstances();
        InputStream is = null;
        try {
            is = ftpClient.retrieveFileStream(filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return is;
    }

    /**
     * 将输入流下载存到指定的File文件中
     */
    public static void saveIsToFile(InputStream is, File file) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            byte[] buffer = new byte[1024 * 10];
            int len = -1;
            while ((len = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭一个输入流
     */
    public static void safeClose(InputStream inputStream) {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException var2) {
                ;
            }
        }

    }

    /**
     * 关闭一个输出流
     */
    public static void safeClose(OutputStream outputStream) {
        if (outputStream != null) {
            try {
                outputStream.close();
            } catch (IOException var2) {
                ;
            }
        }

    }

    /**
     * 文件下载,以流的形式
     */
    public void downObj(String path, File file) {
        InputStream is = getObjInputStream(path);
        saveIsToFile(is, file);
    }
}
